package com.yuliang.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuliang.constants.SystemConstants;
import com.yuliang.domain.R;
import com.yuliang.domain.entity.Menu;
import com.yuliang.domain.entity.RoleMenu;
import com.yuliang.domain.vo.*;
import com.yuliang.enums.AppHttpCodeEnum;
import com.yuliang.exception.SystemException;
import com.yuliang.mapper.MenuMapper;
import com.yuliang.service.MenuService;
import com.yuliang.service.RoleMenuService;
import com.yuliang.utils.BeanCopyUtils;
import com.yuliang.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 菜单权限表(Menu)表服务实现类
 *
 * @author makejava
 * @since 2023-10-07 09:49:57
 */
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    private RoleMenuService roleMenuService;


    @Override
    public R treeSelect() {
        //查询大的目录
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(Menu::getParentId,Menu::getOrderNum);
        List<MenuSelectVo> menuSelectVos = getChildrenSelect(list(queryWrapper));

        return R.okResult(menuSelectVos);
    }



    @Override
    public List<String> selectPermsByUserId(Long id) {
        //id为1为系统管理员，返回所有权限
        if (id.equals(1L)){
            //要求菜单状态正常
            LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(Menu::getMenuType, SystemConstants.MENU,SystemConstants.BUTTON);
            queryWrapper.eq(Menu::getStatus,SystemConstants.STATUS_NORMAL);
            List<Menu> list = list(queryWrapper);
            List<String> ret = new ArrayList<>();
            for (Menu menu:list) {
                ret.add(menu.getPerms());
            }
            return ret;
        }
        //其他人员
        return getBaseMapper().selectPermsByUserId(id);
    }

    /**
     * 菜单
     * @param id
     * @return
     */
    @Override
    public R getRouters(Long id) {
        List<Menu> list = null;
        //管理员
        if (SecurityUtils.isAdmin()){
            //要求菜单状态正常
            LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(Menu::getMenuType, SystemConstants.MENU,SystemConstants.MAIN);
            queryWrapper.eq(Menu::getStatus,SystemConstants.STATUS_NORMAL);
            queryWrapper.orderByAsc(Menu::getParentId,Menu::getOrderNum);
            list = list(queryWrapper);
        }else {//其他人员
            list = getBaseMapper().selectRouterMenuTreeByUserId(id);
        }
        return R.okResult(new RoutersVo(getChildren(list)));
    }


    /**
     * 获取菜单的子元素
     * @param list
     * @return
     */
    public List<Menu> getChildren(List<Menu> list) {
        int start = getParentNum(list);//获取ParentId为0的根节点
        Menu[] menus = (Menu[]) list.toArray(new Menu[0]);
        Menu[] ret = new Menu[start];
        int retNum = 0;
        for (int i = 0;i < menus.length;i++){
            List<Long> childrenList = new ArrayList<>();
            while (start < menus.length && menus[start].getParentId().equals(menus[i].getId())){
                childrenList.add(menus[start].getId());
                start++;
            }
            if (childrenList.size() != 0){
                List<Menu> childrens = listByIds(childrenList);
                menus[i].setChildren(childrens);
            }
        }
        for (Menu menu:menus) {
            if (menu.getParentId().equals(0L) && retNum < 3){
                ret[retNum++] = menu;
            }
        }
        return Arrays.asList(ret);
    }

    /**
     * 获取子节点treeselect   label -->  menuName   <MenuSelectVo>
     * @param list
     * @return
     */
    public List<MenuSelectVo> getChildrenSelect(List<Menu> list) {
        int start = getParentNum(list);//获取ParentId为0的根节点    子节点开始遍历的位置

        List<MenuSelectVo> menuSelectVos = toMenuSelectVo(list);//Menu To MenuSelectVo
        MenuSelectVo[] menus = (MenuSelectVo[]) menuSelectVos.toArray(new MenuSelectVo[0]);

        MenuSelectVo[] ret = new MenuSelectVo[start];//返回值

        int retNum = 0;
        for (int i = 0;i < menus.length;i++){
            List<Long> childrenList = new ArrayList<>();
            for (int l = start;l < menus.length;l++){
                if (menus[l].getParentId().equals(menus[i].getId())){
                    childrenList.add(menus[l].getId());//获取子元素id
                    start++;
                }
            }
            //子元素获取 and vo
            if (childrenList.size() != 0){
                List<Menu> temp = listByIds(childrenList);
                List<MenuSelectVo> childrens = BeanCopyUtils.copyBeanList(temp, MenuSelectVo.class);
                int k = 0;
                for (MenuSelectVo menuSelectVo:childrens) {
                    menuSelectVo.setLabel(temp.get(k++).getMenuName());
                }
                menus[i].setChildren(childrens);
                //设置子子元素
                for (int j = 0;j < childrens.size();j++){
                    List<Long> ids = new ArrayList<>();
                    for (int n = start;n < menus.length;n++){
                        if (menus[n].getParentId().equals(childrens.get(j).getId())){
                            ids.add(menus[n].getId());
                        }
                    }
                    if (ids.size() != 0){
                        List<MenuSelectVo> children_2 = toMenuSelectVo(listByIds(ids));//子子元素
                        childrens.get(j).setChildren(children_2);
                    }
                }
            }
        }
        //目录
        for (MenuSelectVo menu:menus) {
            if (menu.getParentId().equals(0L) && retNum <= 3){
                ret[retNum++] = menu;
            }
        }
        return Arrays.asList(ret);
    }
    /**
     * Menu To MenuSelectVo
     * @param menuList
     * @return
     */
    public List<MenuSelectVo> toMenuSelectVo(List<Menu> menuList){
        List<MenuSelectVo> menuSelectVos = BeanCopyUtils.copyBeanList(menuList, MenuSelectVo.class);//label --> menuName
        int n = 0;
        for (MenuSelectVo menuSelectVo:menuSelectVos) {
            menuSelectVo.setLabel(menuList.get(n++).getMenuName());
        }
        return menuSelectVos;
    }

    /**
     * 获取ParentId为0的根节点的个数
     * @param list
     * @return
     */
    public int getParentNum(List<Menu> list) {
        int ret = 0;
        for (Menu menu:list) {
            if (menu.getParentId().equals(0L)){
                ret++;
            }
        }
        return ret;
    }

    @Override
    public R roleMenuTreeselect(Long id) {
        //role_id 获取菜单并未 set 子元素
        List<Menu> menuList = null;
        List<Long> checkedKeys = null;
        if (id.equals(1L)){//管理员
            LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.orderByAsc(Menu::getParentId,Menu::getOrderNum);
            menuList = list(queryWrapper);
            checkedKeys = getBaseMapper().getAllMenuId();
        }else {//other
            LambdaQueryWrapper<RoleMenu> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(RoleMenu::getRoleId,id);
            List<RoleMenu> list = roleMenuService.list(wrapper);
            List<Long> menuIds = new ArrayList<>();
            for (RoleMenu roleMenu:list) {
                menuIds.add(roleMenu.getMenuId());
            }
//            LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
//            queryWrapper.orderByAsc(Menu::getParentId,Menu::getOrderNum);

            menuList = listByIds(menuIds);
            checkedKeys = getBaseMapper().selectMenuIdByRoleId(id);
        }
        //set子元素
        List<MenuSelectVo> menus = getChildrenSelect(menuList);

        //角色所关联的菜单权限id列表


        return R.okResult(new MenuTreeByIdVo(menus,checkedKeys));
    }

    @Override
    public R menuList(String status, String menuName) {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.hasText(status),Menu::getStatus,status);
        queryWrapper.like(StringUtils.hasText(menuName),Menu::getMenuName,menuName);
        queryWrapper.orderByAsc(Menu::getParentId,Menu::getOrderNum);
        List<Menu> list = list(queryWrapper);
        List<MenuVo> menuVos = BeanCopyUtils.copyBeanList(list, MenuVo.class);
        return R.okResult(menuVos);
    }

    @Override
    public R addMenu(Menu menu) {
        save(menu);
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menu::getMenuName,menu.getMenuName());
        Menu one = getOne(queryWrapper);
        roleMenuService.save(new RoleMenu(1L,one.getId()));
        return R.okResult();
    }

    @Override
    public R getMenuDetail(Long id) {
        Menu menu = getById(id);
        MenuDetailVo menuDetailVo = BeanCopyUtils.copyBean(menu, MenuDetailVo.class);
        return R.okResult(menuDetailVo);
    }

    @Override
    public R updateMenu(Menu menu) {
        if (menu.getParentId().equals(menu.getId())){
            throw new SystemException(AppHttpCodeEnum.MENU_NOT_SELF);
        }
        updateById(menu);
        return R.okResult();
    }

    @Override
    public R deleteMenu(Long menuId) {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menu::getParentId,menuId);
        List<Menu> list = list(queryWrapper);
        if (list.size() > 0){
            throw new SystemException(AppHttpCodeEnum.EXIST_CHILDREN_MENU);
        }
        removeById(menuId);
        return R.okResult();
    }



    //method2
//    @Override
//    public List<Menu> selectRouterMenuTreeByUserId(Long userId) {
//        MenuMapper menuMapper = getBaseMapper();
//        List<Menu> menus = null;
//        //判断是否是管理员
//        if(SecurityUtils.isAdmin()){
//            //如果是 获取所有符合要求的Menu
//            menus = menuMapper.selectAllRouterMenu();
//        }else{
//            //否则  获取当前用户所具有的Menu
//            menus = menuMapper.selectRouterMenuTreeByUserId(userId);
//        }
//        //构建tree
//        //先找出第一层的菜单  然后去找他们的子菜单设置到children属性中
//        List<Menu> menuTree = builderMenuTree(menus,0L);
//        return menuTree;
//    }
//    private List<Menu> builderMenuTree(List<Menu> menus, Long parentId) {
//        List<Menu> menuTree = menus.stream()
//                .filter(menu -> menu.getParentId().equals(parentId))
//                .map(menu -> menu.setChildren(getChildren(menu, menus)))
//                .collect(Collectors.toList());
//        return menuTree;
//    }
//    private List<Menu> getChildren(Menu menu, List<Menu> menus) {
//        List<Menu> childrenList = menus.stream()
//                .filter(m -> m.getParentId().equals(menu.getId()))
//                .map(m->m.setChildren(getChildren(m,menus)))
//                .collect(Collectors.toList());
//        return childrenList;
//    }

}
